package com.zp.mvppractice.io;

import android.database.Cursor;
import android.support.v4.util.Pair;
import android.util.SparseArray;
import com.zp.mvppractice.App;
import com.zp.mvppractice.Constants;
import com.zp.mvppractice.beans.Bill;
import com.zp.mvppractice.beans.Customer;
import com.zp.mvppractice.beans.Product;
import com.zp.mvppractice.beans.ResponseBean;
import com.zp.mvppractice.beans.User;
import com.zp.mvppractice.utils.SPUtils;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.ObservableSource;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Action;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;

/**
 * Created by izp on 2017/5/12.
 */

public class DataCenter {

    private User mUser;
    private SparseArray<Observable> sparseArray = new SparseArray<>();
    private List<Observable> observables = new ArrayList<>();


//{token=rmFktoRLg28dOKx0epYi, mobile=15736096668, version=1.5.3, source=android}

//    [password=111111,source=android,token=,mobile=15736096668,version=1.6.0]
    private DataCenter(){
//        if (AppContext.gDataCenter != null && AppContext.gDataCenter.isLogin()) {
//            String strToken = AppContext.gDataCenter.getMyToken();
//            if (!mMap.containsKey("token")) {
//                mMap.put("token", strToken);
//            }
//            String strMobile = AppContext.gDataCenter.getMyMobile();
//            if (!mMap.containsKey("mobile")) {
//                mMap.put("mobile", strMobile);
//            }
//        }
    }
    public static DataCenter getInstance(){
        return InstanceHolder.sDataCenter;
    }
    private static class InstanceHolder {
        static DataCenter sDataCenter = new DataCenter();
    }
    public void login(){
        Map<String,String> params = getParams();
        params.put("mobile","15736096668");
        params.put("password","111111");
        params.remove("token");
        NetHelper.getInstance().getPaymentButler().login(params)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<ResponseBean<List<User>>>() {
            @Override
            public void onSubscribe(Disposable d) {
//                这里可以showLoading
            }

            @Override
            public void onNext(ResponseBean<List<User>> listResponseBean) {//这里应该要转换一次
                if (listResponseBean.getHead().getResult()>0){
                    mUser = listResponseBean.getBody().getData().get(0);
                    if (null!=mUser){
                        SPUtils.putAndApply(App.getAppContext(), Constants.F_MOBILE,mUser.getMobile());
                        SPUtils.putAndApply(App.getAppContext(), Constants.F_TOKEN,mUser.getToken());
                    }else {
                        onError(new Throwable(""));
                    }
                }

            }

            @Override
            public void onError(Throwable e) {
            }

            @Override
            public void onComplete() {

            }
        });
    }
    public Pair<Observable<ResponseBean<List<User>>>, Disposable> login2(final OnDoListener onDoListener){
        Map<String,String> params = getParams();
        params.put("mobile","15736096668");
        params.put("password","111111");
        Observable<ResponseBean<List<User>>> observable =NetHelper.getInstance().getPaymentButler().login(params)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
        observables.add(observable);
        Disposable disposable =observable
                .subscribe(new Consumer<ResponseBean<List<User>>>() {
                    @Override
                    public void accept(@NonNull ResponseBean<List<User>> listResponseBean) throws Exception {
                        onDoListener.onSuccess(listResponseBean.toString());
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(@NonNull Throwable throwable) throws Exception {
                        onDoListener.onFail(throwable);
                    }
                }, new Action() {
                    @Override
                    public void run() throws Exception {
                        onDoListener.onComplete();
                    }
                }, new Consumer<Disposable>() {
                    @Override
                    public void accept(@NonNull Disposable disposable) throws Exception {
                        onDoListener.onStart(disposable);
                    }
                });
        return new Pair<>(observable,disposable);
    }

    public Pair<Observable<ResponseBean<List<Bill>>>, Disposable> tryGetBills(final OnDoListener onDoListener){
        Observable<ResponseBean<List<Bill>>> observable =NetHelper.getInstance().getPaymentButler().getBills(getParams())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
        observables.add(observable);
        Disposable disposable =observable
                .subscribe(new Consumer<ResponseBean<List<Bill>>>() {
                    @Override
                    public void accept(@NonNull ResponseBean<List<Bill>> listResponseBean) throws Exception {
                        onDoListener.onSuccess(listResponseBean.toString());
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(@NonNull Throwable throwable) throws Exception {
                        onDoListener.onFail(throwable);
                    }
                }, new Action() {
                    @Override
                    public void run() throws Exception {
                        onDoListener.onComplete();
                    }
                }, new Consumer<Disposable>() {
                    @Override
                    public void accept(@NonNull Disposable disposable) throws Exception {

                    }
                });
        return new Pair<>(observable,disposable);
    }

    public Observable<ResponseBean<List<Product>>> tryGetProducts(final OnDoListener<ResponseBean<List<Product>>> onDoListener){
        Observable<ResponseBean<List<Product>>> observable = NetHelper.getInstance().getPaymentButler().getProductss(getParams());

        Observer<ResponseBean<List<Product>>> observer = new Observer<ResponseBean<List<Product>>>() {
            @Override
            public void onSubscribe(Disposable d) {
                onDoListener.onStart(d);
            }

            @Override
            public void onNext(ResponseBean<List<Product>> listResponseBean) {
                onDoListener.onSuccess(listResponseBean);
            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {

            }
        };
        observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(observer);
        return observable;

    }

    public void tryGetCustomers(){
        NetHelper.getInstance().getPaymentButler().getCustomers(getParams())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<ResponseBean<List<Customer>>>() {
            @Override
            public void onSubscribe(Disposable d) {
                
            }

            @Override
            public void onNext(ResponseBean<List<Customer>> listResponseBean) {
            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {

            }
        });
    }

    public Observable<List<User>> readAllRecords() {
        return Observable.create(new ObservableOnSubscribe<List<User>>() {
            @Override
            public void subscribe(ObservableEmitter<List<User>> emitter) throws Exception {
//                订阅一个观察发射器，
                Cursor cursor = null;
                try {
//                    cursor = getReadableDatabase().rawQuery("select * from " + TABLE_NAME, new String[]{});
//                    List<User> result = new ArrayList<>();
//                    while (cursor.moveToNext()) {
//                        result.add(Db.Record.read(cursor));
//                    }
//                    emitter.onNext(result);
                    emitter.onComplete();
                } finally {
                    if (cursor != null) {
                        cursor.close();
                    }
                }
            }
        }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
    }

    private Map<String,String> getParams(){
        Map<String,String> baseParams=new HashMap<>();
        baseParams.put("source", "android");
        baseParams.put("version", "1.5.3");
        baseParams.put("mobile", String.valueOf(SPUtils.get(App.getAppContext(), Constants.F_MOBILE,"")));
        baseParams.put("token", String.valueOf(SPUtils.get(App.getAppContext(), Constants.F_TOKEN,"")));
        return baseParams;
    }

    public void registerThenLogin(){//感觉flatMap用于注册后再登录这个场景并没有用对？没有复用两码，结构也并不清晰
        NetHelper.getInstance().getPaymentButler().register(getParams())
                .subscribeOn(Schedulers.io()) //在IO线程进行网络请求
                .observeOn(AndroidSchedulers.mainThread()) //回到主线程去处理请求注册结果
                .doOnNext(new Consumer<ResponseBean<List<User>>>() {
                    @Override
                    public void accept(@NonNull ResponseBean<List<User>> listResponseBean) throws Exception {
                    //先根据注册的响应结果去做一些操作
                    }
                })
                .observeOn(Schedulers.io())//回到IO线程去发起登录请求,发起请求不应该用subscribeOn么？，
                .flatMap(new Function<ResponseBean<List<User>>, ObservableSource<ResponseBean<List<User>>>>() {
                    @Override
                    public ObservableSource<ResponseBean<List<User>>> apply(@NonNull ResponseBean<List<User>> listResponseBean) throws Exception {
                        return NetHelper.getInstance().getPaymentButler().login(getParams());
//                        这里可以做一个List来储事件，把一个事件转换为多个事件
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<ResponseBean<List<User>>>() {
                    @Override
                    public void accept(@NonNull ResponseBean<List<User>> listResponseBean) throws Exception {

                    }
                });
    }
//    接着用Zip来打包请求:
//    Observable<UserBaseInfoResponse> observable1 =
//            api.getUserBaseInfo(new UserBaseInfoRequest()).subscribeOn(Schedulers.io());
//
//    Observable<UserExtraInfoResponse> observable2 =
//            api.getUserExtraInfo(new UserExtraInfoRequest()).subscribeOn(Schedulers.io());
//
//Observable.zip(observable1, observable2,
//            new BiFunction<UserBaseInfoResponse, UserExtraInfoResponse, UserInfo>() {
//        @Override
//        public UserInfo apply(UserBaseInfoResponse baseInfo,
//                UserExtraInfoResponse extraInfo) throws Exception {
//            return new UserInfo(baseInfo, extraInfo);
//        }
//    }).observeOn(AndroidSchedulers.mainThread())
//            .subscribe(new Consumer<UserInfo>() {
//        @Override
//        public void accept(UserInfo userInfo) throws Exception {
//            //do something;
//        }
//    });



}
